/*
 * Copyright (C) 2018 Logos Technology Ltd.
 */

package com.logos.common.source.network;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.logos.common.source.network.callback.HttpRespondResultCallBack;
import com.logos.common.source.network.entity.FailedNetEntity;
import com.logos.tool.Aes256;
import com.logos.tool.JsonParseUtil;
import com.logos.tool.log.LogUtil;
import com.google.gson.JsonParseException;

import org.json.JSONObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import okhttp3.ResponseBody;

/**
 * 把json转换成Entity
 *
 * @author Young Ken
 */

public class BaseFunction<R, T extends ResponseBody> implements Function<T, R> {

    private HttpRespondResultCallBack mCallback;
    private static final String TAG = "BaseFunction";
    private String jsonString;

    public BaseFunction(HttpRespondResultCallBack callBack) {
        mCallback = callBack;
    }

    @Override
    public R apply(T responseBody) throws Exception {

        try {
            jsonString = new String(responseBody.bytes());
            long startTime = System.currentTimeMillis();
            Type mySuperClass = mCallback.getClass().getGenericSuperclass();
            Type type = ((ParameterizedType) mySuperClass).getActualTypeArguments()[0];
            long endTime = System.currentTimeMillis();
            LogUtil.info(TAG, "time:" + (endTime - startTime)
                    + "\n Thread:" + Thread.currentThread());
            return JsonParseUtil.jsonToMode(jsonString, type);
        } catch (final Exception exception) {
            //in main thread
            Observable.just(0).subscribeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Integer>() {
                        @Override
                        public void accept(Integer integer) throws Exception {
                            if (exception instanceof JsonParseException) {
                                Throwable throwable = new Throwable("parsing exception");
                                FailedNetEntity entity = new FailedNetEntity(ExceptionHandle
                                        .Error.PARSE_ERROR,
                                        exception.getMessage());
                                mCallback.onFailure(throwable, entity);
                                LogUtil.error(TAG, "JsonParseException: "
                                        + LogUtil.getStackTrace(exception)
                                        + "jsonResult: " + jsonString);
                            } else {
                                mCallback.onFailure(new Throwable("other exception"),
                                        new FailedNetEntity(ExceptionHandle.Error.UNKNOWN,
                                                "other exception"));
                                LogUtil.error(TAG, "OtherException: "
                                        + LogUtil.getStackTrace(exception)
                                        + "jsonResult: " + jsonString);
                            }
                        }
                    });
            return null;
        }
    }
}
